package mx.ipn.pruebas;

import javax.xml.namespace.QName;

import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

import mx.ipn.to.ClienteTO;
import mx.ipn.to.UsuarioTO;
import mx.ipn.to.GrupoUsuarioTO;

public class pruebaServicios {
	static RPCServiceClient serviceClient;
	
	public static void inicializar() throws AxisFault{
		serviceClient = new RPCServiceClient();
		Options options = serviceClient.getOptions();
		// EPR del servicio, se puede encontrar en http://localhost:8080/axis2/services/listServices
		EndpointReference targetEPR = new EndpointReference(
				"http://localhost:8080/axis2/services/SAISTServiciosPersistencia");
		options.setTo(targetEPR);
	}
	
	/* 
	 * Como invocar un servicio en donde se le mande un dato primitivo 
	 *
	 * */
	public static void servicioEnviarDatoPrimitivo(){
		// Establecer el tipo de fabrica de DAOs
		
		// Nombre del servicio
		QName opSetFabrica = new QName("http://servicios.ipn.mx",
		"setTipoDeFabrica");
		
		// Parametro a enviar
		int i=1;
		Object[] opSetArgsFabrica = new Object[] { i };
		
		// Invocar servicio
		try{
			serviceClient.invokeRobust(opSetFabrica, opSetArgsFabrica);
		}catch(AxisFault e){ e.printStackTrace(); }
		
		System.out.println("Invocacion Completada, se mando dato primitivo");
	}
	
	/* 
	 * Como invocar un servicio que regrese un dato primitivo 
	 * 
	 * */
	public static void servicioObtenerDatoPrimitivo(){
		// Obtener el tipo de fabrica de DAOs
		
		// Nombre del servicio
		QName opGetFabrica = new QName("http://servicios.ipn.mx",
				"getTipoDeFabrica");
		
		// Paramentro a enviar
		Object[] opGetArgsFabrica = new Object[] {};
		Class[] returnTypes = new Class[] { Integer.class };

		// Parametro a recibir
		Object[] respuesta = null;
		
		// Invocar servicio
		try{
			respuesta = serviceClient.invokeBlocking(opGetFabrica,
				opGetArgsFabrica, returnTypes);
		}catch(AxisFault e){ e.printStackTrace(); }
		
		// Parametro recibido
		int resultado = (Integer) respuesta[0];
		
		System.out.println("Resultado de dato primitivo: "+resultado);
	}
	
	/* 
	 * Como invocar un servicio que regrese un TO 
	 * 
	 * */
	public static ClienteTO servicioObtenerTO() {
		// Obtener el cliente con el id=1
		QName opFindCliente = new QName("http://servicios.ipn.mx",
		"buscarClientePorId");
		
		int id=1;
		Object[] opGetArgsFindCliente = new Object[] { id };
		Class[] returnTypeCliente = new Class[] { ClienteTO.class };

		Object[] respuesta = null;
		
		try{
		respuesta = serviceClient.invokeBlocking(opFindCliente,
				opGetArgsFindCliente, returnTypeCliente);
		}catch(AxisFault e){ e.printStackTrace(); }
		
		ClienteTO clienteTO = (ClienteTO) respuesta[0];

		if (clienteTO == null) {
			System.out.println("El servicio no se completo!");
			return null;
		}
		
		System.out.println("Nombre: " + clienteTO.getNombre());
		
		return clienteTO;
	}
	
	/* 
	 * Como invocar un servicio mandandole un TO 
	 * 
	 * */
	public static void servicioEnviarTO( ClienteTO clienteTO ){
		// Actualizar el cliente con el id=1
		QName opUpdateCliente = new QName("http://servicios.ipn.mx",
		"actualizarCliente");
		
		clienteTO.setNombre("fofolfo");
		//clienteTO.setNombre("rodolfo emmanuel");
		
		Object[] opGetArgsUpdateCliente = new Object[] { clienteTO };
		Class[] returnTypeCliente = new Class[] { Short.class };
		
		Object[] respuesta = null;
		
		try{
		respuesta = serviceClient.invokeBlocking(opUpdateCliente,
				opGetArgsUpdateCliente, returnTypeCliente);
		}catch(AxisFault e){ e.printStackTrace(); }
		
		// Parametro recibido
		short resultado = (Short) respuesta[0];
		
		System.out.println("Resultado de Actualizacion: "+resultado);
		System.out.println("Nombre Actualizado: " + clienteTO.getNombre());
	}
	
	/* 
	 * Como invocar un servicio que regrese un arreglo de TOs 
	 * 
	 * */
	public static void servicioObtenerArregloTOs(){
		// Obtener todos los clientes
		QName opSelectCliente = new QName("http://servicios.ipn.mx",
		"seleccionarClientes");
		
		int id=1;
		Object[] opGetArgsSelectCliente = new Object[] { id };
		Class[] returnTypeCliente = new Class[] { ClienteTO[].class };

		Object[] respuesta = null;
		
		try{
		respuesta = serviceClient.invokeBlocking(opSelectCliente,
				opGetArgsSelectCliente, returnTypeCliente);
		}catch(AxisFault e){ e.printStackTrace(); }
		
		ClienteTO[] clienteTO = (ClienteTO[]) respuesta[0];

		if (clienteTO == null) {
			System.out.println("El servicio no se completo!");
			return;
		}
		
		System.out.println("Clientes Registrados:");
		for(ClienteTO c : clienteTO)
			System.out.println("Nombre: " + c.getNombre());
	}
	
	/* 
	 * Como invocar un servicio que regrese un TO complejo (que contenga otros TOs)
	 * 
	 * */
	public static void servicioObtenerTOComplejo() {
		// Obtener el usuario de nombre contra1 
		QName opFindUsuario = new QName("http://servicios.ipn.mx",
		"buscarUsuarioPorNombre");
		
		String nombre="contra1";
		Object[] opGetArgsFindCliente = new Object[] { nombre };
		Class[] returnTypeCliente = new Class[] { UsuarioTO.class };

		Object[] respuesta = null;
		
		try{
			respuesta = serviceClient.invokeBlocking(opFindUsuario,
				opGetArgsFindCliente, returnTypeCliente);
		}catch(AxisFault e){ e.printStackTrace(); }
		
		UsuarioTO usuarioTO = (UsuarioTO) respuesta[0];
		
		if (usuarioTO == null) {
			System.out.println("El servicio no se completo!");
			return;
		}
		
		GrupoUsuarioTO grupoTO = usuarioTO.getGrupoUsuarioTO();
		
		System.out.println("El Usuario de nombre: " + usuarioTO.getNombreUsuario() +
				", esta en el grupo: " + grupoTO.getNombre() + " ;)");
	}
	
	public static void main(String[] args1) {
		
		try{
			inicializar();
		}catch(AxisFault e){ e.printStackTrace(); }
		
		servicioEnviarDatoPrimitivo();
		servicioObtenerDatoPrimitivo();
		
		ClienteTO clienteTO = servicioObtenerTO();
		servicioEnviarTO(clienteTO);

		servicioObtenerArregloTOs();
		
		servicioObtenerTOComplejo();
	}
}
